在前面幾天探討了元件資料傳遞的方式,不過若想要傳遞的是 DOM 內容,使得元件在不同的地方,可以渲染不同的內容,並且仍保有相同的樣式,則需要透過使用插槽 Slots,將父元件的內容渲染在子元件中指定的位置。
在某些情況下,父元件想要傳遞一些模板片段,並且將這些片段內容渲染在子元件中的指定位置,就可以使用插槽 Slots 來達到此效果。
以下是官方文件的範例
在父元件的<template>
標籤中,寫入欲渲染在子元件 FancyButton 的插槽內容。
<script setup>
import FancyButton from './FancyButton.vue'
</script>
<template>
<FancyButton>
Click me <!-- 插槽內容 -->
</FancyButton>
</template>
在子元件 FancyButton 的<template>
標籤中,寫入<slot>
來標示欲渲染內容的地方。
<template>
<button class="fancy-btn">
<slot/> <!-- 插槽出口 -->
</button>
</template>
最終渲染出來的 HTML 如下:
<button class="fancy-btn">Click me!</button>
此外,當父元件並未提供插植內容時,若想要指定插槽的預設內容,可以將內容寫在<slot>
標籤內。
<button type="reset">
<slot>
Reset <!-- 預設內容 -->
</slot>
</button>
以下是官方文件的範例
當一個元件中使用多個插槽時,需要在子元件的<template>
標籤中,使用<slot>
元素的 name 屬性來定義插槽的名稱。
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
在父元件的<template>
標籤中使用 v-slot 指令(或簡寫為 # )來定義插槽的名稱,其中<template #default>
等同於<template v-slot:default>
,可以指定沒有 name 屬性的 slot 區塊。
<BaseLayout>
<template #header>
<h1>Here might be a page title</h1>
</template>
<template #default>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</template>
<template #footer>
<p>Here's some contact info</p>
</template>
</BaseLayout>
最終渲染出來的 HTML 如下:
<div class="container">
<header>
<h1>Here might be a page title</h1>
</header>
<main>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</main>
<footer>
<p>Here's some contact info</p>
</footer>
</div>
https://book.vue.tw/CH2/2-4-slots.html
https://zh-hk.vuejs.org/guide/components/slots.html
https://www.nielsen.tw/vue/slot/
https://christine52jesus.medium.com/vue3-%E7%B3%BB%E5%88%97-%E4%BB%80%E9%BA%BC%E6%98%AF%E6%8F%92%E6%A7%BD-slots-20a192537b05
https://hackmd.io/@CynthiaChuang/Vue-Study-Notes-Contents/%2F%40CynthiaChuang%2FVue-Study-Notes-Unit06%23Slot-%25E5%2585%2583%25E4%25BB%25B6%25E6%258F%2592%25E6%25A7%25BD